﻿using HDLogCenter.Infrastructure.Config;
using HDLogCenter.Infrastructure.Utils;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace HDLogCenter.Infrastructure.ExternalServices
{
    public class DingTalkAlertService
    {
        private readonly ILogger<DingTalkAlertService> _logger;
        private readonly DingTalkConfig _config;
        private readonly HttpClient _httpClient;
        private readonly Dictionary<string, List<DateTime>> _errorLogs = new Dictionary<string, List<DateTime>>();
        private readonly object _lock = new object();
        private readonly string _accessToken = "fbd0f11eba53eee42eace616dab5bcc455266ad169413bac0a34abbf237ef03e";
        private readonly string _secret = "hilink";
        private DingTalkRobotHelper _robotHelper;

        public DingTalkAlertService(IOptionsMonitor<DingTalkConfig> config, ILogger<DingTalkAlertService> logger)
        {
            _config = config.CurrentValue;
            _logger = logger;
            _httpClient = new HttpClient();
            _robotHelper = new DingTalkRobotHelper(_accessToken, _secret);
        }

        /// <summary>
        /// 记录错误日志并检查是否需要告警
        /// </summary>
        public void RecordErrorLog(string projectCode, string message)
        {
            if (string.IsNullOrEmpty(_config.WebhookUrl))
            {
                _logger.LogWarning("钉钉Webhook未配置，跳过告警");
                return;
            }

            lock (_lock)
            {
                var now = DateTime.Now;

                // 获取或创建项目错误日志列表
                if (!_errorLogs.ContainsKey(projectCode))
                {
                    _errorLogs[projectCode] = new List<DateTime>();
                }

                var projectErrors = _errorLogs[projectCode];

                // 添加当前错误日志时间
                projectErrors.Add(now);

                // 清理1分钟前的记录
                var oneMinuteAgo = now.AddMinutes(-1);
                projectErrors.RemoveAll(time => time < oneMinuteAgo);

                // 检查是否需要告警
                if (projectErrors.Count >= _config.ErrorThreshold)
                {
                    _ = Task.Run(async () => await SendAlertAsync(projectCode, projectErrors.Count, message));

                    // 清空记录，避免重复告警
                    projectErrors.Clear();
                }
            }
        }

        /// <summary>
        /// 发送钉钉告警
        /// </summary>
        private async Task SendAlertAsync(string projectCode, int errorCount, string lastErrorMessage)
        {
            try
            {
                string alertMessage = $"hilink 项目告警\n\n" +
                                 $"项目代码: {projectCode}\n" +
                                 $"错误数量: {errorCount} 条\n" +
                                 $"时间窗口: 1分钟\n" +
                                 $"最后错误: {lastErrorMessage}\n" +
                                 $"告警时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}";

                //var content = new StringContent(json, Encoding.UTF8, "application/json");

                await _robotHelper.SendTextAsync(alertMessage, null, true);
                //var response = await _httpClient.PostAsync(_config.WebhookUrl, content);
                //if (response.IsSuccessStatusCode)
                //{
                //    _logger.LogInformation("钉钉告警发送成功，项目: {ProjectCode}, 错误数量: {ErrorCount}", projectCode, errorCount);
                //}
                //else
                //{
                //    _logger.LogError("钉钉告警发送失败，状态码: {StatusCode}, 项目: {ProjectCode}", response.StatusCode, projectCode);
                //}
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "发送钉钉告警时发生错误，项目: {ProjectCode}", projectCode);
            }
        }

        /// <summary>
        /// 清理过期数据
        /// </summary>
        public void CleanupExpiredData()
        {
            lock (_lock)
            {
                var now = DateTime.Now;
                var oneMinuteAgo = now.AddMinutes(-1);

                foreach (var project in _errorLogs.Keys.ToList())
                {
                    var projectErrors = _errorLogs[project];
                    projectErrors.RemoveAll(time => time < oneMinuteAgo);

                    // 如果项目没有错误日志了，移除项目
                    if (projectErrors.Count == 0)
                    {
                        _errorLogs.Remove(project);
                    }
                }
            }
        }

        public void Dispose()
        {
            _httpClient?.Dispose();
        }
    }
}
